package com.rent.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rent.beans.request.PublishRequest;
import com.rent.beans.resp.HouseListResp;
import com.rent.beans.resp.HouseRegionResp;
import com.rent.constants.SysConstant;
import com.rent.entity.House;
import com.rent.entity.HouseImg;
import com.rent.entity.PublishRecord;
import com.rent.enums.PublishStatusEnum;
import com.rent.mapper.HouseMapper;
import com.rent.service.HouseImgService;
import com.rent.service.HouseService;
import com.rent.service.PublishRecordService;
import com.rent.utils.RedisGeoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author
 * @since 2021-06-05
 */
@Slf4j
@Service
public class HouseServiceImpl extends ServiceImpl<HouseMapper, House> implements HouseService {

    @Autowired
    HouseMapper houseMapper;
    @Autowired
    HouseImgService houseImgService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RedisGeoUtil redisGeoUtil;

    @Autowired
    PublishRecordService publishRecordService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void publishHouse(PublishRequest publishRequest, Integer userId) {
        House house = new House();
        BeanUtil.copyProperties(publishRequest, house);
        //经纬度保留6位小数，多了腾讯地图报错
//        house.setLat(NumberUtil.roundDown(publishRequest.getLat(),6));
//        house.setLng(NumberUtil.roundDown(publishRequest.getLng(),6));
        //特殊设置一些
        house.setCreateUserId(userId);
        house.setPayType(publishRequest.getPayTypeIndex());
        house.setHouseType(publishRequest.getHouseTypeIndex());
        house.setDescription(publishRequest.getDescription());
        if (CollectionUtils.isNotEmpty(publishRequest.getHouseConfigIdList())) {
            house.setConfig(JSONObject.toJSONString(publishRequest.getHouseConfigIdList()));
        }
        house.setPublishStatus(PublishStatusEnum.PUB.getCode());
        boolean saveResult = save(house);

        //经纬度存redis
        Point point = new Point(house.getLng().doubleValue(), house.getLat().doubleValue());
        redisGeoUtil.addGeoPoint(SysConstant.HOUSE_GEO_PREFIX, point, house.getId());
        //处理图片
        List<String> houseImgs = publishRequest.getHouseImgs();
        List<HouseImg> imageEntityList = new ArrayList<>();
        for (String url : houseImgs) {
            HouseImg houseImg = new HouseImg();
            houseImg.setHouseId(house.getId());
            houseImg.setImgUrl(url);
            imageEntityList.add(houseImg);
        }
        houseImgService.saveBatch(imageEntityList);
        //保存发布记录
        PublishRecord publishRecord = new PublishRecord();
        publishRecord.setHouseId(house.getId());
        publishRecord.setPublishUserId(userId);
        publishRecordService.save(publishRecord);
    }


    @Override
    public List<HouseListResp> nearbyHouse() {
        //查询中心点
        //AppUserPosition userPos = findByUserId(userId);
        String redisKey = SysConstant.HOUSE_GEO_PREFIX + "userPos.getLoginProvinceCode()";
        //半径
        BigDecimal lat = new BigDecimal("39.981768");
        BigDecimal lng = new BigDecimal("116.312785");
        Circle circle = new Circle(lng.doubleValue(), lat.doubleValue(), Metrics.MILES.getMultiplier()); //Metrics.KILOMETERS.getMultiplier()

        //命令行参数
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs
                .newGeoRadiusArgs()
                .includeDistance() //距离
                .includeCoordinates() //??不知道啥意思
                .sortAscending() //按距离排序
                .limit(100000);//查前几条，就是分页，这里没必要分页，一下查出来也没多少，让前端去分页
        GeoResults<RedisGeoCommands.GeoLocation<Object>> results = redisTemplate.opsForGeo().geoRadius(redisKey, circle, args);

        //返回是这样式的数据：：RedisGeoCommands.GeoLocation(name=1005, point=Point [x=116.319522, y=40.148395])
        System.out.println(results);
        List<HouseListResp> nearbyPeopleList = new ArrayList<>();

        for (GeoResult<RedisGeoCommands.GeoLocation<Object>> obj : results) {
            System.out.println(obj.getContent());

            Long nearHouseId = Long.valueOf((String) obj.getContent().getName());//userId
            double dist = obj.getDistance().getValue();//距离
            //查附近的人信息
            House house = getById(nearHouseId);
            HouseListResp resp = new HouseListResp();
            BeanUtil.copyProperties(house, resp);
            //resp.setDistance(String.valueOf(NumberUtil.round(dist,2)));
            nearbyPeopleList.add(resp);
        }
        return nearbyPeopleList;
    }

    @Override
    public List<House> findByHouseIdList(List<Integer> houseIds) {
        return houseMapper.findByHouseIdList(houseIds);
    }

    @Override
    public List<HouseRegionResp> getHouseRegionList() {
        return this.houseMapper.getHouseRegionList();
    }

    @Override
    public List<House> getListByCityAndDistinct(String city, String district) {
        QueryWrapper<House> eq = new QueryWrapper<House>().eq("city", city).eq("district", district);
        return this.houseMapper.selectList(eq);
    }
}
